package com.xjrh.traintravel.collector.common;

import com.xjrh.common.core.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 编码转换工具类
 *
 * @author snps
 * @create 2022-01-18 8:24
 * @describe
 **/
@Slf4j
public class CodeConvertor {

    public static final char CHAR_0 = '0';

    /**
     * 字节数组转16进制字符串
     * @param bytes 字节数组
     * @return 16进制字符串
     */
    public static String bytes2HexString(byte[] bytes) {
        StringBuffer hexString = new StringBuffer();
        String hex;

        for (int i=0; i<bytes.length; i++) {
            hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            hexString.append(hex.toUpperCase());
        }
        return hexString.toString();
    }

    /**
     * 16进制字符串转字节数组
     * @param hexString 16进制字符串
     * @return 字节数组
     */
    public static byte[] hexString2Bytes(String hexString) {
        // 1个字节等于2个16进制字符。除以2得到字节数组需要声明的长度
        int l = hexString.length() / 2;
        byte[] bytes = new byte[l];

        for (int i=0; i<l; i++) {
            bytes[i] = (byte) Integer.valueOf(hexString.substring(i*2, i*2+2), 16).byteValue();
        }
        return bytes;
    }

    /**
     * 字符串转16进制字符串
     * @param str 字符串
     * @return 16进制字符串
     */
    public static String string2HexString(String str) {
        StringBuffer hexString = new StringBuffer();

        for (int i=0; i<str.length(); i++) {
            int ch = (int) str.charAt(i);
            String hexStr = Integer.toHexString(ch);
            hexString.append(hexStr);
        }
        return hexString.toString();
    }

    /**
     * 16进制字符串转符串转
     * @param hexString 16进制符串转
     * @return 符串转
     */
    public static String hexString2String(String hexString) {
        StringBuilder string = new StringBuilder();

        for (int i=0; i<hexString.length()-1; i+=2) {
            // grab the hex in pairs
            String output = hexString.substring(i, (i+2));
            // convert hex to decimal
            int decimal = Integer.parseInt(output, 16);
            // convert the decimal to character
            string.append((char) decimal);

        }
        return string.toString();
    }

    /**
     * 字符转字节
     * @param ch 字符
     * @return 字节
     */
    public static Byte char2Byte(Character ch) {
        return Integer.valueOf((int) ch).byteValue();
    }

    /**
     * 10进制数字转16进制字符串
     * @param v 10进制数字
     * @param len 占用字节数
     * @return 16进制字符串
     */
    public static String intToHexString(int v, int len) {
        len<<=1;
        String hexString = Integer.toHexString(v);
        int n = len - hexString.length();
        if (n > 0) {
            for (int i=0; i<n; i++) {
                hexString = "0" + hexString;
            }
        }
        return hexString.toUpperCase();
    }

    public static String longToHexString(long v, int len) {
        len<<=1;
        String hexString = Long.toHexString(v);
        int n = len - hexString.length();
        if (n > 0) {
            for (int i=0; i<n; i++) {
                hexString = "0" + hexString;
            }
        }
        return hexString.toUpperCase();
    }

    /**
     * ip地址 转1 6进制字符串
     * @param ip ip地址
     * @return String 16进制字符串
     */
    public static String ip2HexString(String ip) {
        if (ip == null || ip.trim().equals("") || ip.indexOf(".") == -1) {
            return "";
        }

        String[] arysIpNumber = ip.split("\\.");
        StringBuilder sbuHexString = new StringBuilder();
        for (String ipNumber : arysIpNumber) {
            sbuHexString.append(CodeConvertor.intToHexString(Integer.parseInt(ipNumber), 1));
        }
        return sbuHexString.toString();
    }

    /**
     * 16进制字符串 转 ip地址
     * @param hexString 16进制字符串
     * @return String ip地址
     */
    public static String hexString2Ip(String hexString) {
        if (StringUtil.isEmpty(hexString) || hexString.length() != 8) {
            return "";
        }

        StringBuilder sbuIp = new StringBuilder();
        sbuIp.append(Integer.parseInt(hexString.substring(0, 2), 16));
        sbuIp.append(".");
        sbuIp.append(Integer.parseInt(hexString.substring(2, 4), 16));
        sbuIp.append(".");
        sbuIp.append(Integer.parseInt(hexString.substring(4, 6), 16));
        sbuIp.append(".");
        sbuIp.append(Integer.parseInt(hexString.substring(6), 16));
        return sbuIp.toString();
    }

    /**
     * 字节数组转16进制字符串
     * @param bytes 字节数组
     * @return v
     */
    public static String bytes2HexString2(byte[] bytes) {
        if(bytes == null || bytes.length <= 0) {
            return null;
        }

        StringBuilder hexString = new StringBuilder("");

        for (int i=0; i<bytes.length; i++) {
            int v = bytes[i] & 0xFF;
            String hexStr = Integer.toHexString(v);
            if (hexStr.length() < 2) {
                hexString.append(0);
            }
            hexString.append(hexStr);
        }
        return hexString.toString();
    }

    /**
     * 接收字节数组并转换为16进制字符串
     * @param bytes
     * @return
     */
    public static String receiveBytes2HexString(byte[] bytes) {
        try {
            String hexString = bytes2HexString2(bytes);
            hexString = hexString.toUpperCase();
            return hexString;
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("接受字节数组并转换为16进制字符串-发生异常!");
        }
        return null;
    }

    /**
     * "7dd",4,'0'==>"07dd"
     * @param input 需要补位的字符串
     * @param size 补位后的最终长度
     * @param symbol 按symol补充 如'0'
     * @return
     * N_TimeCheck中用到了
     */
    public static String fill(String input, int size, char symbol) {
        while (input.length() < size) {
            input = symbol + input;
        }
        return input;
    }

    /**
     * 16进制 转 二进制数组
     *
     * @param hexString
     * @param digit
     * @return
     */
    public static int[] hexString2Bin(String hexString, int digit) {
        String bin = Integer.toBinaryString(Integer.parseInt(hexString, 16));
        int binLength = bin.length();

        int diff = digit - binLength;
        StringBuilder sbu = new StringBuilder();
        for (int i=0; i<diff; i++) {
            sbu.append("0");
        }
        sbu.append(bin);
        bin = sbu.toString();

        int[] arysBit = new int[digit];
        for (int i=0; i<arysBit.length; i++) {
            arysBit[i] = bin.charAt(arysBit.length - i - 1) - CHAR_0;
        }
        return arysBit;
    }

    /**
     * 二进制 转 16进制
     *
     * @param binary
     * @return
     */
    public static String bin2HexString(String binary) {
        if (ObjectUtils.isEmpty(binary) || binary.length()%8 != 0) {
            return "";
        }

        StringBuilder sbu = new StringBuilder();
        int iTemp;
        for (int i=0; i<binary.length(); i+=4) {
            iTemp = 0;
            for (int j=0; j<4; j++) {
                iTemp += Integer.parseInt(binary.substring(i+j, i+j+1)) << (4-j-1);
            }
            sbu.append(Integer.toHexString(iTemp));
        }
        return sbu.toString();
    }


}